package com.decent.wx.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.decent.entity.common.Message;
import com.decent.enums.MessageEnum;
import com.decent.util.HttpUtil;
import com.decent.util.MessageUtils;
import com.decent.wx.entity.*;
import com.decent.wx.service.MeService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author 王雪杰
 * @date 2021/8/28 16:57
 */
@Service
@Slf4j
public class MeServiceImpl implements MeService {
    @Resource
    private WxSendMessageConfig sendConfig;

    /**
     * 发送模板消息
     *
     * @return Message
     */
    @Override
    public Message send() {
        String accessToken = getAccessToken();
        //openId:oSbEy5MkdJZByQBO-jhWcKNxNhOs
        HashMap<String, String> map = new HashMap<>(5);
        map.put("thing1", o2Json(new SendValue("339208499")));
        map.put("time5", o2Json(new SendValue("2015年01月05日")));
        map.put("thing9",o2Json(new SendValue("TIT创意园")));
        map.put("thing25", o2Json(new SendValue("广州市新港中路397号")));
        map.put("thing20",o2Json(new SendValue("广州市新港中路397号")));
        System.out.println("请求参数map：" + JSON.toJSONString(map));
//        BasicNameValuePair param1 = new BasicNameValuePair("access_token", accessToken);
        BasicNameValuePair param2 = new BasicNameValuePair("touser", "oSbEy5MkdJZByQBO-jhWcKNxNhOs");
        BasicNameValuePair param3 = new BasicNameValuePair("template_id", "iQo38G4U2ZgU0T29JJhEvucFq94TlZsaAW2lJae9mQk");

        BasicNameValuePair param4 = new BasicNameValuePair("data", JSON.toJSONString(map));

        List<BasicNameValuePair> basicNameValuePairs = Arrays.asList(param2, param3, param4);
        System.out.println("##订阅发送JSON数据请求: " + JSON.toJSONString(basicNameValuePairs));
        String s = HttpUtil.sendPost(basicNameValuePairs, "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken);
        return MessageUtils.buildMsg(MessageEnum.GENERAL_REQUEST_SUCCESS, s);
    }

    /**
     * 获得openId
     *
     * @param code 前端wx.login(Object object)获得
     * @return openid
     * @throws Exception Exception
     */
    @Override
    public String getOpenId(String code) throws Exception {
        System.out.println("code" + code);
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        //自己的appid
        url += "?appid=" + sendConfig.getAppId();
        //自己的appSecret
        url += "&secret=" + sendConfig.getSecret();
        url += "&js_code=" + code;
        url += "&grant_type=authorization_code";
        url += "&connect_redirect=1";
        String res = null;
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // DefaultHttpClient();
        HttpGet httpget = new HttpGet(url);    //GET方式
        CloseableHttpResponse response = null;
        // 配置信息
        RequestConfig requestConfig = RequestConfig.custom()          // 设置连接超时时间(单位毫秒)
                .setConnectTimeout(5000)                    // 设置请求超时时间(单位毫秒)
                .setConnectionRequestTimeout(5000)             // socket读写超时时间(单位毫秒)
                .setSocketTimeout(5000)                    // 设置是否允许重定向(默认为true)
                .setRedirectsEnabled(false).build();           // 将上面的配置信息 运用到这个Get请求里
        httpget.setConfig(requestConfig);                         // 由客户端执行(发送)Get请求
        response = httpClient.execute(httpget);                   // 从响应模型中获取响应实体
        HttpEntity responseEntity = response.getEntity();
        System.out.println("响应状态为:" + response.getStatusLine());
        if (responseEntity != null) {
            res = EntityUtils.toString(responseEntity);
            System.out.println("响应内容长度为:" + responseEntity.getContentLength());
            System.out.println("响应内容为:" + res);
        }
        // 释放资源
        if (httpClient != null) {
            httpClient.close();
        }
        if (response != null) {
            response.close();
        }
        JSONObject jo = JSON.parseObject(res);
        String openid = jo.getString("openid");
        System.out.println("openid=" + openid);
        return openid;
    }

    /**
     * 获得access_token
     *
     * @return String
     */
    @Override
    public String getAccessToken() {
        String http = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
                sendConfig.getAppId(), sendConfig.getSecret());

        System.out.println(http);
        String s = HttpUtil.sendGet(http);
        System.out.println("响应内容为:" + s);
        AccessToken accessToken = JSONObject.parseObject(s, AccessToken.class);
        System.out.println("accessToken=" + accessToken.getAccessToken());
        return accessToken.getAccessToken();
    }

    private String o2Json(SendValue sendValue) {
        return JSON.toJSONString(sendValue);
    }

    @Data
    static class SendValue {
        public SendValue(String value) {
            this.value = value;
        }

        private Object value;
    }

    /**
     * 发送订阅消息sendTemplateMessage
     * 小程序订阅消息,发送服务通知
     *
     * @param touser     接收者（用户）的 openid
     * @param templateId 所需下发的模板消息的id
     * @param page       点击模板卡片后的跳转页面，仅限本小程序内的页面。支持带参数,（示例index?foo=bar）。该字段不填则模板无跳转。
     */
    @Override
    public void subscribeMessage(String touser, String templateId, String page, Map<String, TemplateData> map) {

        String accessToken = getAccessToken();

        //拼接数据
//        SubscribeMessage subscribeMessage = new SubscribeMessage();
//        subscribeMessage.setTouser(touser);
//        subscribeMessage.setTemplate_id(templateId);
//        subscribeMessage.setPage(page);
//        subscribeMessage.setData(map);
//        String json = JSONObject.toJSONString(subscribeMessage);
//        log.info("##订阅发送JSON数据请求:  " + json);
//        List<BasicNameValuePair> basicNameValuePairs = Arrays.asList(new BasicNameValuePair("data", json));
//        System.out.println("basicNameValuePairs=\n" + JSON.toJSONString(basicNameValuePairs));
//        String ret = HttpUtil.sendPost(basicNameValuePairs, "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken);
        HashMap<String, Object> param = new HashMap<String, Object>() {
            {
                put("touser", touser);
                put("template_id", templateId);
                put("data", map);
                put("page", page);
                put("miniprogram_state", "developer");
            }
        };
        String ret = HttpUtil.sendPost("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken, param);
        //如果不想找sendPost，可以借用Unirest 来发送 2选1 引的jar放在最下方了
//        JsonNode ret = null;
//        try {
//            ret = Unirest.post(Wechat.SUBSCRIBEMESSAGE + accessToken).body(json).asJson().getBody();
//        } catch (UnirestException e) {
//            e.printStackTrace();
//        }

        log.info("##订阅发送JSON数据返回:  " + ret);
        System.out.println(ret);
    }

    /**
     * 获取当前帐号下的个人模板列表
     *
     * @return WxMessage
     */
    @Override
    public WxMessage getTemplateList() {
        String accessToken = getAccessToken();
        String url = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=" + accessToken;
        String json = HttpUtil.sendGet(url);
        System.out.println("##订阅发送JSON数据请求:  " + json);
        return JSONObject.parseObject(json, WxMessage.class);
    }
}
